package geppetto.reordering;

import geppetto.cat.alignments.AlignmentsSet;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.ExtractedPhrasePair;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.SentenceInfo;
import geppetto.reordering.graph.GraphWeightScorer;
import geppetto.reordering.graph.ReorderingGraph;
import geppetto.reordering.graph.scorers.UnweightedGraphScorer;

import java.util.List;

public class GraphPhraseReorderingCalculator extends MSDReorderingCalculator{

	public GraphPhraseReorderingCalculator(AlignmentsSet set) {
		super(set);
	}

	@Override
	public ReorderingInfo getReorderingInfo(ExtractedPhrasePair epp) {
		ReorderingInfo info = new ReorderingInfo();
		SentenceInfo senInfo = epp.getSentenceInfo();
		if(senInfo.getCustomInfo("reordering-graph") == null){
			ReorderingGraph graph = getReorderingGraph(senInfo);
			senInfo.setCustomInfo("reordering-graph", graph);
		}
		
		ReorderingGraph graph = (ReorderingGraph)epp.getSentenceInfo().getCustomInfo("reordering-graph");
		
		List<ExtractedPhrasePair> previousPhrases = graph.getPreviousNodes(epp);
		double monoAlphaP = 0;
		double swapAlphaP = 0;
		double otherAlphaP = 0;
		double betaP = graph.getPathsFromNode(epp);
		
		for(ExtractedPhrasePair pair : previousPhrases){
			int orientation = graph.getOrientation(pair, epp);
			double weight = graph.getPathsToNode(pair) * graph.getScorer().scorePrevArc(epp, pair);
			if(orientation == MSDOrientationCodes.MONO_CODE){
				monoAlphaP += weight;
			}
			if(orientation == MSDOrientationCodes.SWAP_CODE){
				swapAlphaP += weight;
			}
			if(orientation == MSDOrientationCodes.OTHER_CODE){
				otherAlphaP += weight;
			}
		}
		
		//double normalizer = getNormalizer(new double[]{monoAlphaP, swapAlphaP, otherAlphaP});
		double normalizer = graph.getNumberOfPaths() / betaP;
		if(normalizer == 0){
			System.out.println(monoAlphaP);
			System.out.println(swapAlphaP);
			System.out.println(otherAlphaP);
			System.out.println("[(" + epp.getSourceStartPos() + ","+ epp.getSourceEndPos() + ")(" + epp.getForeignStartPos() + "," + epp.getForeignEndPos() + ")]" );
			graph.printGraph();
			System.out.println("bah");
			System.exit(0);
		}
		info.addPrevWordOrientation(MSDOrientationCodes.MONO_CODE, monoAlphaP / normalizer);
		info.addPrevWordOrientation(MSDOrientationCodes.SWAP_CODE, swapAlphaP / normalizer);
		info.addPrevWordOrientation(MSDOrientationCodes.OTHER_CODE, otherAlphaP / normalizer);
		
		List<ExtractedPhrasePair> followingPhrases = graph.getFollowingNodes(epp);
		double monoAlphaN = 0;
		double swapAlphaN = 0;
		double otherAlphaN = 0;
		double betaN = graph.getPathsToNode(epp);
		
		for(ExtractedPhrasePair pair : followingPhrases){
			int orientation = graph.getOrientation(epp, pair);
			double weight = graph.getPathsFromNode(pair) * graph.getScorer().scoreNextArc(epp, pair);
			if(orientation == MSDOrientationCodes.MONO_CODE){
				monoAlphaN += weight;
			}
			if(orientation == MSDOrientationCodes.SWAP_CODE){
				swapAlphaN += weight;
			}
			if(orientation == MSDOrientationCodes.OTHER_CODE){
				otherAlphaN += weight;
			}
		}
		
		//normalizer = getNormalizer(new double[]{monoAlphaN, swapAlphaN, otherAlphaN});
		normalizer = graph.getNumberOfPaths() / betaN;
		
		info.addNextWordOrientation(MSDOrientationCodes.MONO_CODE,epp.getScore() * monoAlphaN / normalizer);
		info.addNextWordOrientation(MSDOrientationCodes.SWAP_CODE,epp.getScore() * swapAlphaN / normalizer);
		info.addNextWordOrientation(MSDOrientationCodes.OTHER_CODE,epp.getScore() * otherAlphaN / normalizer);
	
		return info;
	}

	public static void main(String[] args) throws Exception{		
		ExtractedPhrasePair[] phrases = ReorderingGraph.getTestPhrases();
		int i = 0;
		GraphPhraseReorderingCalculator calc = new GraphPhraseReorderingCalculator(null);
		for(ExtractedPhrasePair pair : phrases){
			i++;
			ReorderingInfo info = calc.getReorderingInfo(pair);
			
			System.out.println(i + 
					" - " +
					info.getPreviousWordOrientationCounts().get(MSDOrientationCodes.MONO_CODE) + 
					" " +
					info.getPreviousWordOrientationCounts().get(MSDOrientationCodes.SWAP_CODE) + 
					" " +
					info.getPreviousWordOrientationCounts().get(MSDOrientationCodes.OTHER_CODE) + 
					" " +
					info.getNextWordOrientationCounts().get(MSDOrientationCodes.MONO_CODE) + 
					" " +
					info.getNextWordOrientationCounts().get(MSDOrientationCodes.SWAP_CODE) + 
					" " +
					info.getNextWordOrientationCounts().get(MSDOrientationCodes.OTHER_CODE));
		}

	}

	
	protected ReorderingGraph getReorderingGraph(SentenceInfo senInfo){
		ReorderingGraph graph = new ReorderingGraph(senInfo);
		graph.setScorer(new UnweightedGraphScorer());
		graph.generateWeightedGraphPaths();
		return graph;
	}
	
	public double getNormalizer(double[] values){
		double total = 0;
		for(double v : values){
			total+=v;
		}		
		return total;
	}

}
